package go_service

import (
	"context"
	"fmt"
	"os/exec"
	"strconv"
	"strings"
)

// ServiceStatus 表示服务的详细状态信息
type ServiceStatus struct {
	Name          string
	Description   string
	Active        bool
	Running       bool
	Enabled       bool
	MainPID       int
	Memory        string
	CPU           string
	State         string
	SubState      string
	LoadState     string
	ActiveState   string
	UnitFileState string
	Since         string
	Started       string
	MainProcess   string
}

// GetServiceStatus 获取服务的详细状态信息
//
// 参数:
//
//	ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//
//	*ServiceStatus: 服务的详细状态信息结构体
//	error: 如果获取成功返回nil，否则返回对应的错误
//
// 示例:
//
//	service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//	ctx := context.Background()
//
//	status, err := service.GetServiceStatus(ctx)
//	if err != nil {
//	    fmt.Printf("获取状态失败: %v\n", err)
//	    return
//	}
//
//	fmt.Printf("服务状态: %s\n", status.State)
//	fmt.Printf("运行状态: %t\n", status.Running)
//	fmt.Printf("主进程PID: %d\n", status.MainPID)
//	fmt.Printf("内存使用: %s\n", status.Memory)
func (s *Service) GetServiceStatus(ctx context.Context) (*ServiceStatus, error) {
	// 使用 systemctl show 获取详细信息
	cmd := exec.CommandContext(ctx, "systemctl", "show", s.Name, "--property=Id,Description,ActiveState,SubState,LoadState,UnitFileState,MainPID,MemoryCurrent,CPUUsageNSec,ExecMainPID,ExecStart,ActiveEnterTimestamp,InactiveEnterTimestamp")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to get service status: %w", err)
	}

	status := &ServiceStatus{
		Name: s.Name,
	}

	// 解析输出
	lines := strings.Split(string(output), "\n")
	for _, line := range lines {
		if line == "" {
			continue
		}
		parts := strings.SplitN(line, "=", 2)
		if len(parts) != 2 {
			continue
		}
		key, value := parts[0], parts[1]

		switch key {
		case "Description":
			status.Description = value
		case "ActiveState":
			status.ActiveState = value
			status.Active = value == "active"
		case "SubState":
			status.SubState = value
			status.Running = value == "running"
		case "LoadState":
			status.LoadState = value
		case "UnitFileState":
			status.UnitFileState = value
			status.Enabled = strings.Contains(value, "enabled")
		case "MainPID":
			if pid, err := strconv.Atoi(value); err == nil {
				status.MainPID = pid
			}
		case "MemoryCurrent":
			if value != "[not set]" {
				status.Memory = formatMemory(value)
			}
		case "CPUUsageNSec":
			if value != "[not set]" {
				status.CPU = formatCPU(value)
			}
		case "ExecStart":
			status.MainProcess = value
		case "ActiveEnterTimestamp":
			status.Since = value
		case "InactiveEnterTimestamp":
			status.Started = value
		}
	}

	return status, nil
}

// ListServices 列出所有已安装的服务
//
// 参数:
//
//	ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//
//	[]string: 服务名称列表（不包含.service后缀）
//	error: 如果获取成功返回nil，否则返回对应的错误
//
// 示例:
//
//	ctx := context.Background()
//	services, err := ListServices(ctx)
//	if err != nil {
//	    fmt.Printf("获取服务列表失败: %v\n", err)
//	    return
//	}
//
//	fmt.Printf("发现 %d 个服务:\n", len(services))
//	for _, service := range services {
//	    fmt.Printf("  - %s\n", service)
//	}
func ListServices(ctx context.Context) ([]string, error) {
	cmd := exec.CommandContext(ctx, "systemctl", "list-unit-files", "--type=service", "--no-pager")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to list services: %w", err)
	}

	lines := strings.Split(string(output), "\n")
	var services []string
	for _, line := range lines[1:] { // 跳过标题行
		parts := strings.Fields(line)
		if len(parts) >= 1 && strings.HasSuffix(parts[0], ".service") {
			serviceName := strings.TrimSuffix(parts[0], ".service")
			services = append(services, serviceName)
		}
	}

	return services, nil
}

// formatMemory 格式化内存显示
func formatMemory(memoryStr string) string {
	// 这里简化处理，实际应该解析字节数并转换为合适的单位
	return memoryStr
}

// formatCPU 格式化CPU显示
func formatCPU(cpuStr string) string {
	// 这里简化处理，实际应该解析纳秒并转换为合适的单位
	return cpuStr
}

// IsServiceLoaded 检查服务是否已加载到Systemd
//
// 参数:
//
//	ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//
//	bool: 如果服务已加载返回true，否则返回false
//
// 示例:
//
//	service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//	ctx := context.Background()
//
//	if service.IsServiceLoaded(ctx) {
//	    fmt.Println("服务已加载到Systemd")
//	} else {
//	    fmt.Println("服务未加载到Systemd")
//	}
func (s *Service) IsServiceLoaded(ctx context.Context) bool {
	cmd := exec.CommandContext(ctx, "systemctl", "is-active", s.Name)
	_, err := cmd.CombinedOutput()
	return err == nil
}

// GetServiceUptime 获取服务运行时间
//
// 参数:
//
//	ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//
//	string: 服务的运行时间描述
//	error: 如果获取成功返回nil，否则返回对应的错误
//
// 示例:
//
//	service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//	ctx := context.Background()
//
//	uptime, err := service.GetServiceUptime(ctx)
//	if err != nil {
//	    fmt.Printf("获取运行时间失败: %v\n", err)
//	    return
//	}
//	fmt.Printf("服务运行时间: %s\n", uptime)
func (s *Service) GetServiceUptime(ctx context.Context) (string, error) {
	status, err := s.GetServiceStatus(ctx)
	if err != nil {
		return "", err
	}

	if !status.Running {
		return "not running", nil
	}

	return status.Since, nil
}
